#include "stdafx.h"

s_functions_3 _GirderAPI;
PFTree DUITree = NULL;

static const char* PluginVersion = "4.0";

HINSTANCE _hInstance;
SetWinTextPlugin _AtlModule;


extern "C" BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
{
	_hInstance = hInstance;
    return _AtlModule.DllMain(dwReason, lpReserved); 
}

extern "C" void WINAPI gir_version(char* data, int size)
{
	strncpy_s(data, size, PluginVersion, strlen(PluginVersion));
}

extern "C" void WINAPI gir_name(char* data, int size)
{
	ATL::CStringA name;
	name.LoadString(IDS_PROJNAME);

	strncpy_s(data, size, name, name.GetLength());
}

extern "C" void WINAPI gir_description(char* data, int size)
{
	ATL::CStringA description;
	description.LoadString(IDS_DESCRIPTION);

	strncpy_s(data, size, description, description.GetLength());
}

extern "C" int WINAPI gir_devicenum()
{
	return SetWinTextPlugin::PLUGIN_ID;
}

extern "C" int WINAPI gir_requested_api(int max_api)
{
	return 3;
}

extern "C" int WINAPI gir_open(int gir_major_ver, int gir_minor_ver, int gir_micro_ver, pFunctions3 p)
{
	ATLASSERT(false);

	PCHAR filename = PathExpand("%GIRDER%Plugins\\UI\\SetWinText.xml");
	DUITree = LoadDUI(filename);
	SafeFree(filename);

	if(DUITree == NULL)
	{
		ATL::CStringA pluginName;
		pluginName.LoadStringW(_hInstance, IDS_PROJNAME);

		GirderLogMessageEx(pluginName.GetString(), "Unable to load DUI resource.", GLM_ERROR_ICON);
		return GIR_FALSE;
	}
	return GIR_TRUE;
}

extern "C" int WINAPI gir_close()
{
	if(DUITree != NULL)
		DeleteFTree(DUITree);

	return GIR_TRUE;
}

extern "C" int WINAPI gir_info(int message, int wparam, int lparam)
{
	if(message == GIRINFO_MAINWIN_CLOSE)
	{
	}
	return GIR_TRUE;
}

extern "C" void* WINAPI gir_dui(PFTree tree, PFTreeNode node, PBaseNode base,
	int duiIndex, int message, WPARAM wParam, LPARAM lParam, void* userData)
{
	switch(message)
	{
		case duOnHookCommand:
		case duOnHookConditional:
			LockTree(tree, TreeLockWrite);
			MergeDUITrees(tree, DUITree, message);
			UnlockTree(tree, TreeLockWrite);
			break;
		case duOnUnHookCommand:
		case duOnUnHookConditional:
			LockTree(tree, TreeLockWrite);
			UnmergeDUITrees(tree, DUITree, message);
			UnlockTree(tree, TreeLockWrite);
			break;
		case duOnGetDefaults:
			//TODO: establish sensible defaults in the command
			//      structure.
			break;
    }
    return NULL;
}

extern "C" int WINAPI TargetCallback(HWND hWnd, PCommand command, CRITICAL_SECTION* cs, void* userData)
{
	if(userData == NULL)
		return retStopProcessing;

	CommandSettings& settings(*static_cast<CommandSettings*>(userData));

	ATL::CStringA text = settings.GetText();
	if(settings.GetParseText())
	{
		PCHAR parsedText = ParseString(const_cast<PCHAR>(text.GetString()));
		if(parsedText != NULL)
			text = parsedText;

		SafeFree(parsedText);
	}
	ATL::CStringW textW;
	textW = text;

	if(settings.GetUseSendMessage())
		::SendMessage(hWnd, WM_SETTEXT, 0, (LPARAM)textW.GetString());
	else
		::SetWindowText(hWnd, textW.GetString());
	
	return retContinue;
}

extern "C" int WINAPI gir_event(PFTreeNode node, CRITICAL_SECTION* cs, PEventElement Event, char* status,  int statuslen)
{
	CommandSettings settings;
	bool loaded;

	EnterCriticalSection(cs);
	PCommand command = (PCommand)node->Data;
	loaded = settings.Load(command);
	LeaveCriticalSection(cs);

	if(!loaded)
		return retStopProcessing;

	TargetEnum(command, cs, TargetCallback, &settings);
	return retContinue;
}




